package easyjs

import (
	"os"
	"os/exec"
	"path/filepath"
	"time"

	"gitee.com/haodreams/golib/easyurl"
	"gitee.com/haodreams/golib/logs"
	"gitee.com/haodreams/libs/config"
	"gitee.com/haodreams/libs/easy"
	"gitee.com/haodreams/libs/routine"
	"github.com/atotto/clipboard"
)

type System struct {
}

func (m *System) Name() string {
	return "sys"
}

// 复制到剪切板
func (m *System) Copy(text string) {
	clipboard.WriteAll(text)
}

/**
 * @description: 获取配置文件
 * @param {string} key
 * @return {*}
 */
func (m *System) GetValue(key string) string {
	return config.String(key)
}

// 系统退出函数
func (m *System) Exit() {
	routine.Stop()
}

// 读取全部行，出错显示msg+错误提示
func (m *System) ReadLines(path, msg string) []string {
	lines, err := easy.ReadLines(path)
	if err != nil {
		logs.LiteWarn(msg, err)
	}
	return lines
}

// 读取文件
func (m *System) ReadFile(path, msg string) any {
	data, err := os.ReadFile(path)
	if err != nil {
		logs.LiteWarn(msg, err)
		return nil
	}
	return string(data)
}

/**
 * @description: 删除文件
 * @param {string} path
 * @return {*}
 */
func (m *System) Remove(path string) any {
	_, err := os.Stat(path)
	if err != nil {
		return nil
	}
	err = os.Remove(path)
	if err != nil {
		return err
	}
	return nil
}

/**
 * @description: 文件或目录是否存在
 * @param {string} path
 * @return {*}
 */
func (m *System) IsExist(path string) bool {
	_, err := os.Stat(path)
	return err == nil
}

// 读取文件目录
func (m *System) ReadDir(path string) (paths []string) {
	ps, err := os.ReadDir(path)
	if err != nil {
		logs.Warn(err)
		return nil
	}
	for _, p := range ps {
		paths = append(paths, p.Name())
	}
	return
}

/**
 * @description: 是否是一个文件
 * @param {string} path
 * @return {*}
 */
func (m *System) IsFile(path string) bool {
	f, err := os.Stat(path)
	if err != nil {
		return false
	}
	if f.IsDir() {
		return false
	}
	return true
}

/**
 * @description: 新建一个目录
 * @param {string} path
 * @return {*}
 */
func (m *System) Mkdir(path string) bool {
	err := easy.MkdirAll(path)
	return err != nil
}

/**
 * @description: 文件改名
 * @param {*} old
 * @param {string} new
 * @return {*}
 */
func (m *System) Rename(old, new string) any {
	_, err := os.Stat(old)
	if err == nil {
		err = os.Rename(old, new)
		if err != nil {
			return err.Error()
		}
		return nil
	}
	return err.Error()
}

/**
 * @description: 获取文件的更新时间
 * @param {string} path
 * @return {*}
 */
func (m *System) FileModiTime(path string) int64 {
	fi, err := os.Stat(path)
	if err != nil {
		return -1
	}
	return fi.ModTime().Unix()
}

/**
 * @description: 是否是一个目录
 * @param {string} path
 * @return {*}
 */
func (m *System) IsDir(path string) bool {
	f, err := os.Stat(path)
	if err != nil {
		return false
	}
	if f.IsDir() {
		return true
	}
	return false
}

/**
 * @description: 追加的方式文件
 * @param {*} path
 * @param {string} data
 * @return {*}
 */
func (m *System) AppendFile(path, data string) any {
	f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
	if err != nil {
		return err
	}
	defer f.Close()
	_, err = f.WriteString(data)
	return err
}

/**
 * @description: 写文件
 * @param {*} path
 * @param {string} data
 * @return {*}
 */
func (m *System) WriteFile(path, data string) any {
	dir := filepath.Dir(path)
	os.MkdirAll(dir, 0755)
	return os.WriteFile(path, []byte(data), 0644)
}

/**
 * @description: 读取文件的内容
 * @param {string} path
 * @return {*}
 */
func (m *System) RemoveFile(path string) any {
	_, err := os.Stat(path)
	if err != nil {
		return nil
	}
	err = os.Remove(path)
	if err != nil {
		return err
	}
	return nil
}

// 是否是工作日
func (m *System) IsWorkday() bool {
	// 获取当前工作日
	day := time.Now().Weekday()
	if day == 0 || day == 6 {
		return false // 示例代码，返回 false 表明是周六或周日，非工作日
	}

	return true // 示例代码，返回 true 表明是工作日
}

// 是否是交易日
func (m *System) IsTradeDay() bool {
	if m.IsWorkday() {
		lines, err := easy.ReadLines("data/holiday.csv")
		if err != nil {
			return true
		}
		now := easy.FormatNow(easy.YMD)
		for _, line := range lines {
			if line == now {
				return false
			}
		}
		return true
	}

	return false
}

func (m *System) Sleep(ms int) {
	if ms == 0 {
		time.Sleep(time.Millisecond * 1000)
		return
	}
	time.Sleep(time.Millisecond * time.Duration(ms))
}

// 获取一个进程的PID
func (m *System) Kill(pid int) any {
	process, err := os.FindProcess(int(pid))
	if err != nil {
		return err.Error()
	}
	err = process.Kill()
	if err != nil {
		return err.Error()
	}

	return nil
}

// 获取一个进程的PID
func (m *System) CreateProcess(binPath string) int {
	cmd := exec.Command(binPath)
	err := cmd.Start()
	if err != nil {
		return 0
	}
	return cmd.Process.Pid
}

func (m *System) GET(url string) any {
	data, code, err := easyurl.Get(url, nil)
	if err != nil {
		return map[string]any{"code": 0, "error": err.Error()}
	}
	return map[string]any{"data": string(data), "code": code, "error": nil}
}

func (m *System) POST(url string, jsdata string) any {
	data, code, err := easyurl.Post(url, easyurl.NewOptions(easyurl.WithBody([]byte(jsdata))))
	if err != nil {
		return map[string]any{"code": 0, "error": err.Error()}
	}
	return map[string]any{"data": string(data), "code": code, "error": nil}
}

func (m *System) PostJSON(url string, jsdata string) any {
	data, code, err := easyurl.JSON(url, jsdata)
	if err != nil {
		return map[string]any{"code": 0, "error": err.Error()}
	}
	return map[string]any{"data": string(data), "code": code, "error": nil}
}

func (m *System) SaveConfig() any {
	return config.Save()
}

// 执行命令
func (m *System) Exec(cmd ...string) {
	if len(cmd) == 0 {
		return
	}
	command := exec.Command(cmd[0], cmd[1:]...)
	command.Stdout = os.Stdout
	command.Stderr = os.Stderr
	err := command.Run()
	if err != nil {
		logs.Warn(err)
	}
}
